package vn.edu.hut.soict.translate.transform.utils;

import simplenlg.features.Feature;
import simplenlg.features.NumberAgreement;
import simplenlg.framework.InflectedWordElement;
import simplenlg.framework.LexicalCategory;
import simplenlg.framework.NLGElement;
import simplenlg.framework.WordElement;

public class GrammaticalNumber extends WordTransformUtils {

	public static GrammaticalConstant pronounNumber(String pronoun) {
		if (pronoun.equalsIgnoreCase("I") || pronoun.equalsIgnoreCase("he") || pronoun.equalsIgnoreCase("she") || pronoun.equalsIgnoreCase("it")) {
			return GrammaticalConstant.SINGULAR;
		}
		if (pronoun.equalsIgnoreCase("we") || pronoun.equalsIgnoreCase("they")) {
			return GrammaticalConstant.PLURAL;
		}
		if (pronoun.equalsIgnoreCase("you")) {
			return GrammaticalConstant.BOTH;
		}
		return GrammaticalConstant.ERROR;
	}

	public static GrammaticalConstant nounOrPronounNumber(String noun) {
		GrammaticalConstant number = pronounNumber(noun);
		if (number != GrammaticalConstant.ERROR) {
			return number;
		}

		if (noun.equals(nounDecline(noun, GrammaticalConstant.SINGULAR))) {
			return GrammaticalConstant.SINGULAR;
		}
		if (noun.equals(nounDecline(noun, GrammaticalConstant.PLURAL))) {
			return GrammaticalConstant.PLURAL;
		}
		return GrammaticalConstant.ERROR;
	}

	public static GrammaticalConstant verbNumber(String verb) {
		if (verb.equalsIgnoreCase("are") || verb.equalsIgnoreCase("were")) {
			return GrammaticalConstant.PLURAL;
		}
		if (verb.equalsIgnoreCase("am") || verb.equalsIgnoreCase("is") || verb.equalsIgnoreCase("was")) {
			return GrammaticalConstant.SINGULAR;
		}
		if (VerbTransformUtils.form(verb) == GrammaticalConstant.PRESENT_SIMPLE_WITH_SINGULAR) {
			return GrammaticalConstant.SINGULAR;
		}
		if (VerbTransformUtils.form(verb) == GrammaticalConstant.PAST_SIMPLE) {
			return GrammaticalConstant.BOTH;
		}
		return GrammaticalConstant.PLURAL;
	}

	public static GrammaticalConstant determinerNumber(String determiner) {
		if (determiner.equalsIgnoreCase("one") || determiner.equalsIgnoreCase("a") || determiner.equalsIgnoreCase("an")) {
			return GrammaticalConstant.SINGULAR;
		}
		if (determiner.equalsIgnoreCase("this") || determiner.equalsIgnoreCase("that")) {
			return GrammaticalConstant.SINGULAR;
		}
		if (determiner.equalsIgnoreCase("these") || determiner.equalsIgnoreCase("those")) {
			return GrammaticalConstant.PLURAL;
		}
		return GrammaticalConstant.BOTH;
	}

	public static boolean isAgree(GrammaticalConstant numberType1, GrammaticalConstant numberType2) {
		if (numberType1 == GrammaticalConstant.BOTH || numberType2 == GrammaticalConstant.BOTH) {
			return true;
		}
		if (numberType1 == numberType2 && (numberType1 == GrammaticalConstant.SINGULAR || numberType1 == GrammaticalConstant.PLURAL)) {
			return true;
		}
		return false;
	}
	
	public static boolean isAgree(String subject, String verb) {
		GrammaticalConstant numberType1 = GrammaticalNumber.nounOrPronounNumber(subject);
		GrammaticalConstant numberType2 = GrammaticalNumber.verbNumber(verb);
		String bareVerb = VerbTransformUtils.conjugate(verb, GrammaticalConstant.BARE);
		if (subject.equalsIgnoreCase("I") && numberType2 == GrammaticalConstant.PLURAL) {
			return true;
		}
		if (subject.equalsIgnoreCase("I") && bareVerb.equalsIgnoreCase("be")) {
			if (verb.equals("am") || verb.equalsIgnoreCase("was")) {
				return true;
			}
		}
		if (subject.equalsIgnoreCase("we") && bareVerb.equalsIgnoreCase("be")) {
			if (verb.equals("are")) {
				return true;
			}
		}
		return isAgree(numberType1, numberType2);
	}

	public static String nounDecline(String noun, GrammaticalConstant number) {
		WordElement word = lexicon.getWordFromVariant(noun, LexicalCategory.NOUN);
		InflectedWordElement inflWord = new InflectedWordElement(word);
		NLGElement element;

		switch (number) {
			case SINGULAR:
				// e.g. mouse
				inflWord.setFeature(Feature.NUMBER, NumberAgreement.SINGULAR);
				element = realiser.realise(inflWord);
				return element.toString();
			case PLURAL:
				// e.g. mice
				inflWord.setFeature(Feature.NUMBER, NumberAgreement.PLURAL);
				element = realiser.realise(inflWord);
				return element.toString();
		}

		return null;
	}

	public static String verbConjugate(String verb, GrammaticalConstant number) {
		if (number == GrammaticalConstant.SINGULAR) {
			if (verb.equalsIgnoreCase("are")) {
				return "is";
			}
			if (verb.equalsIgnoreCase("were")) {
				return "was";
			}
			if (VerbTransformUtils.form(verb) == GrammaticalConstant.BARE) {
				return VerbTransformUtils.conjugate(verb, GrammaticalConstant.PRESENT_SIMPLE_WITH_SINGULAR);
			}
		}
		if (number == GrammaticalConstant.PLURAL) {
			if (verb.equalsIgnoreCase("am")) {
				return "are";
			}
			if (verb.equalsIgnoreCase("is")) {
				return "are";
			}
			if (verb.equalsIgnoreCase("was")) {
				return "were";
			}
			if (VerbTransformUtils.form(verb) == GrammaticalConstant.PRESENT_SIMPLE_WITH_SINGULAR) {
				return VerbTransformUtils.conjugate(verb, GrammaticalConstant.BARE);
			}
		}
		return verb;
	}

	public static String verbConjugate(String verb, String subject) {
		GrammaticalConstant number = nounOrPronounNumber(subject);
		GrammaticalConstant form = VerbTransformUtils.form(verb);
		if (number == GrammaticalConstant.ERROR || form == GrammaticalConstant.ERROR) {
			return null;
		}
		if (subject.equalsIgnoreCase("I")) {
			if (form == GrammaticalConstant.BARE || form == GrammaticalConstant.PRESENT_SIMPLE_WITH_SINGULAR) {
				verb = VerbTransformUtils.conjugate(verb, GrammaticalConstant.BARE);
				if (verb.equalsIgnoreCase("be")) {
					return "am";
				}
				return verb;
			}
			if (form == GrammaticalConstant.PAST_SIMPLE) {
				if (verb.equalsIgnoreCase("were")) {
					return "was";
				}
			}
		}
		if (number == GrammaticalConstant.SINGULAR && form == GrammaticalConstant.BARE) {
			return VerbTransformUtils.conjugate(verb, GrammaticalConstant.PRESENT_SIMPLE_WITH_SINGULAR);
		}
		if (number == GrammaticalConstant.PLURAL && form == GrammaticalConstant.PRESENT_SIMPLE_WITH_SINGULAR) {
			verb = VerbTransformUtils.conjugate(verb, GrammaticalConstant.BARE);
			if (subject.equalsIgnoreCase("we") && verb.equalsIgnoreCase("be")) {
				return "are";
			}
			return verb;
		}
		return verbConjugate(verb, number);
	}

	public static String determinerDecline(String determiner, GrammaticalConstant number) {
		if (number == GrammaticalConstant.SINGULAR) {
			if (determiner.equalsIgnoreCase("these")) {
				return "this";
			}
			if (determiner.equalsIgnoreCase("those")) {
				return "that";
			}
		}
		if (number == GrammaticalConstant.PLURAL) {
			if (determiner.equalsIgnoreCase("one") || determiner.equalsIgnoreCase("a") || determiner.equalsIgnoreCase("an")) {
				return "";
			}
			if (determiner.equalsIgnoreCase("this")) {
				return "these";
			}
			if (determiner.equalsIgnoreCase("that")) {
				return "those";
			}
		}
		return determiner;
	}

}
